package com.hang.service.impl;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.util.StrUtil;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.DeleteObjectsRequest;
import com.hang.exception.MyException;
import com.hang.exception.MyExceptionEnum;
import com.hang.service.IFileService;
import com.hang.util.ConstantOssPropertiesUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.UUID;

@Service
@Slf4j
public class FileServiceImpl implements IFileService {
    //允许上传的文件类型
    private static final String[] FILE_TYPE = new String[]{".jpg",".jpeg",".png",".doc",".docx",".txt",".md",".pdf",".xls",".xlsx"};

    @Override
    public String upload(MultipartFile file) {
        //允许上传的文件格式
        if(!checkFileLegal(file.getOriginalFilename())){
            throw new MyException(MyExceptionEnum.FIlE_TYPE_ERROR);
        }

        String endpoint = ConstantOssPropertiesUtils.ENDPOINT;
        String accessKeyId = ConstantOssPropertiesUtils.ACCESS_KEY_ID;
        String accessKeySecret = ConstantOssPropertiesUtils.SECRET;
        String bucketName = ConstantOssPropertiesUtils.BUCKET;
        // 创建OSSClient实例。
        OSS ossClient = null;
        try {
            ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
            // 上传文件流。
            InputStream inputStream = file.getInputStream();
            String fileName = file.getOriginalFilename();
            //生成随机唯一值，使用uuid，添加到文件名称里面
            String uuid = UUID.randomUUID().toString().replaceAll("-", "");
            fileName = uuid + fileName;
            //按照当前日期，创建文件夹，上传到创建文件夹里面
            //  2021/02/02/01.jpg
            String timeUrl = new DateTime().toString("yyyy/MM/dd");
            fileName = "fileSystem/" + timeUrl + "/" + fileName;
            //调用方法实现上传
            ossClient.putObject(bucketName, fileName, inputStream);
            // 关闭OSSClient。
            ossClient.shutdown();
            //上传之后文件路径
            //返回地址
            return "https://" + bucketName + "." + endpoint + "/" + fileName;
        }catch (IOException ioe){
            log.error(ioe.toString());
            return null;
        }finally {
            //遇到异常也要将资源进行关闭
            assert ossClient != null;
            ossClient.shutdown();
        }
    }

    /**
     * 删除单个文件
     * @param url
     */
    @Override
    public void delete(String url) {
        String bucketName = ConstantOssPropertiesUtils.BUCKET;
        String endpoint = ConstantOssPropertiesUtils.ENDPOINT;

        //处理url
        log.info("============入参：{}", url);
        String path = url.substring(("https://" + bucketName + "." + endpoint + "/").length());
        log.info("============path：{}", path);
        ossDelete(Collections.singletonList(path));
    }

    /**
     * 删除多个文件
     * @param urlList
     */
    @Override
    public void delete(List<String> urlList) {
        String bucketName = ConstantOssPropertiesUtils.BUCKET;
        String endpoint = ConstantOssPropertiesUtils.ENDPOINT;

        List<String> keys = new ArrayList<>();
        urlList.forEach(
                url ->{
                    keys.add(url.substring(("https://" + bucketName + "." + endpoint + "/").length()));
                }
        );
        ossDelete(keys);
    }

    private void ossDelete(List<String> urlList){
        OSS ossClient = null;
        String endpoint = ConstantOssPropertiesUtils.ENDPOINT;
        String accessKeyId = ConstantOssPropertiesUtils.ACCESS_KEY_ID;
        String accessKeySecret = ConstantOssPropertiesUtils.SECRET;
        String bucketName = ConstantOssPropertiesUtils.BUCKET;
        try {
            ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);

            DeleteObjectsRequest deleteObjectsRequest = new DeleteObjectsRequest(bucketName);
            deleteObjectsRequest.setKeys(urlList);
            ossClient.deleteObjects(deleteObjectsRequest);
        }catch (Exception e){
            //错误处理
            log.error(e.toString());
        }finally {
            assert ossClient!=null;
            ossClient.shutdown();
        }
    }

    /**
     * 校验图片格式是否符合
     * @param suffixType
     * @return
     */
    private boolean checkFileLegal(String suffixType){
        for (String type : FILE_TYPE) {
            if(StrUtil.endWithIgnoreCase(suffixType,type)){
                return true;
            }
        }
        return false;
    }
}
